package com.baiku.sanhos.utils.model.core;

import com.baiku.sanhos.utils.model.consts.BodyConsts;
import com.baiku.sanhos.utils.model.consts.EndConsts;
import com.baiku.sanhos.utils.model.consts.HeaderConsts;
import com.baiku.sanhos.utils.model.entity.SanhosItemInventory;
import com.baiku.sanhos.utils.model.util.CreateNewFile;
import com.baiku.sanhos.utils.model.util.ElsxFontStyle;
import com.baiku.sanhos.utils.model.util.ReadInventoryFile;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class CreatePrintData implements HeaderConsts, BodyConsts, EndConsts {
    private static Workbook workbook;
    @Autowired
    ReadInventoryFile readInventoryFile;
    @Autowired
    CreateNewFile createNewFile;

    @Value("${modelItemInventoryPath}")
    String modelItemInventoryPath ;

    /**
     * 设置头部数据
     *
     * @param name     姓名
     * @param username 账号
     * @param date     传递null 默认为当前日期
     * @param list     项目费用清单
     */

    public void writeData(String name, Object date, String username,String doctor, List<SanhosItemInventory> list,String alipayQrCode) throws IOException {
        BufferedInputStream bufferedInputStream = readInventoryFile.readModelFile();
        // 将支付宝支付二维码字符串转换为图片
        BufferedImage qrCodeImage = generateQrCodeImage(alipayQrCode);
        // 将二维码图片保存为文件
        File qrCodeFile = new File("qrcode.png"); // 替换为您希望保存图片的文件路径和名称
        saveQrCodeImageToFile(qrCodeImage, qrCodeFile);

        workbook = new XSSFWorkbook(bufferedInputStream);

        //二维码插入到Excel
        setQrCode();
        setHeaderData(name, date, username);
        setBodyData(list);
        setEndData(doctor);


        BufferedOutputStream outputStream = createNewFile.create(username, date);
        workbook.write(outputStream);

        outputStream.flush();
        outputStream.close();
        bufferedInputStream.close();
    }

    //二维码保存到本项目
    private void saveQrCodeImageToFile(BufferedImage qrCodeImage, File file) throws IOException {
        ImageIO.write(qrCodeImage, "png", file);
    }

    //生成二维码数据
    private BufferedImage generateQrCodeImage(String alipayQrCode) {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        hints.put(EncodeHintType.MARGIN, 1);

        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix;
        try {
            bitMatrix = qrCodeWriter.encode(alipayQrCode, BarcodeFormat.QR_CODE, 300, 300, hints);
        } catch (WriterException e) {
            e.printStackTrace();
            return null;
        }

        BufferedImage qrCodeImage = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < 300; x++) {
            for (int y = 0; y < 300; y++) {
                int color = bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF;
                qrCodeImage.setRGB(x, y, color);
            }
        }

        return qrCodeImage;
    }

    /**
     * 把二维码放到Excel中
     */
    private void setQrCode() throws IOException {
        String fileName="qrcode.png";
        Sheet sheet = workbook.getSheetAt(DEFAULT_SHEET);
        FileInputStream is = new FileInputStream(fileName);
        byte[] bytes = IOUtils.toByteArray(is);
        int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
        CreationHelper helper = workbook.getCreationHelper();
        ClientAnchor anchor = helper.createClientAnchor();
        Drawing<?> drawing = sheet.createDrawingPatriarch();

        anchor.setRow1(0); // param2是行号
        anchor.setCol1(5); // param1是列号
        // 插入图片
        Picture pict = drawing.createPicture(anchor, pictureIdx);
        // 调整图片占单元格百分比的大小，1.0就是100%
        pict.resize(1.0);
        is.close();

    }

    private void setHeaderData(String name, Object date, String username) {
        Sheet sheet = workbook.getSheetAt(DEFAULT_SHEET);
        //获取姓名位置
        Row nameRow = sheet.getRow(NAME_INDEX[0]);//行数从0开始
        Cell cell = nameRow.getCell(NAME_INDEX[1]);//列从0开始
        cell.setCellValue(name);
        //获取日期位置
        Row dateRow = sheet.getRow(DATE_INDEX[0]);//行数从0开始
        cell = dateRow.getCell(DATE_INDEX[1]);//列从0开始
        if (date == null) {
            cell.setCellValue(LocalDate.now().toString());
        }
        if (date instanceof Date) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            cell.setCellValue(sdf.format(dateRow));
        } else {
            assert date != null;
            cell.setCellValue(date.toString());
        }
        //获取账号位置
        Row usernameRow = sheet.getRow(USERNAME_INDEX[0]);//行数从0开始
        cell = usernameRow.getCell(USERNAME_INDEX[1]);//列从0开始
        cell.setCellValue(username);
    }

    /**
     * 设置主题数据
     *
     * @param listInventory 挂号清单实体类
     */
    private void setBodyData(List<SanhosItemInventory> listInventory) {
        Sheet sheet = workbook.getSheetAt(DEFAULT_SHEET);
        CellStyle style = ElsxFontStyle.fontTypeCenter(workbook, (short) 16);
        if (!listInventory.isEmpty()) {
            double amountPrice = 0;
            double totalPrice;
            for (SanhosItemInventory sanhosItemInventory : listInventory) {
                sheet.shiftRows(ITEM[0], sheet.getLastRowNum(), 1);
                // 获取要插入的行
                Row row = sheet.createRow(ITEM[0]);
                //获取项目位置
                Cell cell = row.createCell(ITEM[1]);
                cell.setCellValue(sanhosItemInventory.getItem());
                cell.setCellStyle(style);
                //获取数量位置
                cell = row.createCell(NUMBER[1]);
                cell.setCellValue(sanhosItemInventory.getCount());
                cell.setCellStyle(style);

                //数据单价位置
                cell = row.createCell(UNIT_PRICE[1]);
                cell.setCellValue(sanhosItemInventory.getUnitPrice());
                cell.setCellStyle(style);
                //获取总价位置
                cell = row.createCell(TOTAL_PRICE[1]);
                //计算每项总价
                totalPrice = sanhosItemInventory.getUnitPrice() * sanhosItemInventory.getCount();
                cell.setCellValue(totalPrice);
                cell.setCellStyle(style);
                //计算费用总价
                amountPrice += totalPrice;

                //合并单元格 起始行 结束行 起始列 结束列
                CellRangeAddress mergedRegion1 = new CellRangeAddress(ITEM[0], ITEM[0], 0, 1);
                sheet.addMergedRegion(mergedRegion1);
                CellRangeAddress mergedRegion2 = new CellRangeAddress(ITEM[0], ITEM[0], 4, 5);
                sheet.addMergedRegion(mergedRegion2);

                BorderStyle border = BorderStyle.THIN;
                RegionUtil.setBorderBottom(border, new CellRangeAddress(ITEM[0], ITEM[0], 0, 5), sheet);  // 设置下框线
                RegionUtil.setBorderLeft(border, new CellRangeAddress(ITEM[0], ITEM[0], 0, 0), sheet);  // 设置左
                RegionUtil.setBorderRight(border, new CellRangeAddress(ITEM[0], ITEM[0], 5, 5), sheet);  // 设置右
            }
            //获取费用位置
            Row amountRow = sheet.getRow(TOTAL_AMOUNT[0]);//行数从0开始
            Cell cell = amountRow.getCell(TOTAL_AMOUNT[1]);//列从0开始
            cell.setCellValue(amountPrice);
            cell.setCellStyle(style);
        }
    }

    private void setEndData(String doctor){
        Sheet sheet = workbook.getSheetAt(DEFAULT_SHEET);
        //获取姓名位置
        Row nameRow = sheet.getRow(DOCTOR_INDEX[0]);//行数从0开始 6
        Cell cell = nameRow.getCell(DOCTOR_INDEX[1]);//列从0开始 5
        cell.setCellValue(doctor);
    }
}
